#!/usr/bin/wish

# this version finally without the infimous addrows code...
# 2.4.08 chk

# variable definitions and default values:
set nru 0
set RUNNING 0
set pd [pwd] ; # current working directory is program directory
cd
set wd [pwd]
set sd [pwd] ; set sdl $sd ; # saving directory
set COMMENT ""
set tipeb 100 ; set TIMEPERBIN $tipeb ; # time per bin in millisec
set binu 40 ; set BINNUM $binu ; # initial bin number
set tmpfile "[pwd]/.emil.dat"
set TAXMIN "0" ; set TAXMAX $binu ; set YAXMIN "0" ; set YAXMAX ""
set COUNTPROG "$pd/counter2"
set stretchval 1.0
set stretchv $stretchval ; # stretch factor for coincidences
set gpcnt 0 ; # counter for gnuplot calls
set cv0 0 ; set cv1 0 ; set cv2 0 ; set cv3 0 ; # for display

# main button tree
frame .mainknobs
button .mainknobs.start -text "start" -command runproc
bind .mainknobs.start <Return> {.mainknobs.start invoke}
pack .mainknobs.start -side left
button .mainknobs.stop -text "stop" -command haltbutton
bind .mainknobs.stop <Return> {.mainknobs.stop invoke}
pack .mainknobs.stop -side left
button .mainknobs.clear -text "clear" -command clearbutt
bind .mainknobs.clear <Return> {.mainknobs.clear invoke}
pack .mainknobs.clear -side left
pack .mainknobs


# entry for bin number
frame .binnum
label .binnum.txt -text "number of time bins:"
entry .binnum.entry -width 10 -relief sunken -bd 2 -textvariable binu
bind .binnum.entry <Return> {
    if {$binu > 0 && $binu<10000} {
	set BINNUM [expr int($binu)]
    }
    set binu $BINNUM
}
pack .binnum.txt .binnum.entry -side left
pack .binnum

# entry for time per bin
frame .tiperbin
label .tiperbin.txt -text "time per bin in msec:"
entry .tiperbin.entry -width 10 -relief sunken -bd 2 -textvariable tipeb
bind .tiperbin.entry <Return> {
    if {$tipeb >= 5.0} {
	set TIMEPERBIN [expr int(10*$tipeb)/10.0]
    }
    set tipeb $TIMEPERBIN
}
pack .tiperbin.txt .tiperbin.entry -side left
pack .tiperbin

# stretch factor entry
frame .stf
label .stf.t -text "coincidence stretch factor:"
entry .stf.e -width 5 -relief sunken -bd 2 -textvariable stretchv
bind .stf.e <Return> {
    if {$stretchv >= 1.0} {
	set stretchval [expr int(10*$stretchv)/10.0]
    }
    set stretchv $stretchval
}
pack .stf.t .stf.e -side left
pack .stf

# diagnosis widgets:
frame .diag
label .diag.l1 -text "number of gnuplot calls: "
label .diag.l2 -width 6 -textvariable gpcnt
pack .diag.l1 .diag.l2 -side left
# pack .diag

# readout
set FNT "-*-courier-*-r-*-*-36-180-*-*-*-*-*-*"
frame .cnts -borderwidth 2 -relief ridge
label .cnts.t0 -text "counter 0: " -font $FNT 
label .cnts.c0 -width 8 -textvariable cv0 -font $FNT -anchor e -fg red
label .cnts.t1 -text "counter 1: " -font $FNT
label .cnts.c1 -width 8 -textvariable cv1 -font $FNT -anchor e -fg blue
label .cnts.t2 -text "counter 2: " -font $FNT
label .cnts.c2 -width 8 -textvariable cv2 -font $FNT -anchor e -fg magenta
label .cnts.t3 -text "counter 3: " -font $FNT
label .cnts.c3 -width 8 -textvariable cv3 -font $FNT -anchor e -fg cyan
grid .cnts.t0 .cnts.c0
grid .cnts.t1 .cnts.c1
grid .cnts.t2 .cnts.c2
grid .cnts.t3 .cnts.c3
pack .cnts

# file operation buttons
frame .fops
button .fops.save -text "save" -command savebutton
button .fops.exit -text "exit" -command exitbutton
button .fops.print -text "print" -command printbutton
bind .fops.save <Return> {.fops.save invoke}
bind .fops.exit <Return> {.fops.exit invoke}
bind .fops.print <Return> {.fops.pint invoke}
pack .fops.save .fops.exit .fops.print -side left
pack .fops

# axis options
frame .axops
button .axops.taxis -text "time axis" -command taxisbutton
button .axops.yaxis -text "y axis" -command yaxisbutton
bind .axops.taxis <Return> {.axops.taxis invoke}
bind .axops.yaxis <Return> {.axops.yaxis invoke}
pack .axops.taxis .axops.yaxis -side left
pack .axops

# -------------------------------------------------------------
# working procedures 

#procedure to open gnuplot
set gnu 1      ;# file handle
proc gnuopen {} {
    global gnu
    set gnu [open {| gnuplot -title  counters 2>/dev/null} w]
}
gnuopen

# procedure to refresh gnuplot
proc regnu {} {
    global gnu wd TAXMIN TAXMAX YAXMIN YAXMAX tmpfile stretchval gpcnt
    puts $gnu "plot \[$TAXMIN\:$TAXMAX\] \[$YAXMIN\:$YAXMAX\] '$tmpfile' using 0:1 notitle with  lines lt 1 lw 3, '$tmpfile' using 0:2  notitle with lines lt 3 lw 3,  '$tmpfile' using 0:($stretchval*\$3)  notitle with lines lt 4 lw 3,  '$tmpfile' using 0:4  notitle with lines lt 5 lw 3"
    flush $gnu
    incr gpcnt
}

# procedure to close gnuplot
proc gnuclose {} {
    global gnu
    puts $gnu "exit"
    close $gnu
}
# proc bgerror {msg } { exit }

# procedure for lin scale 
proc gnulin {} {
    global gnu
    puts $gnu "set nologscale y"
    flush $gnu
}
proc gnulog {} {
    global gnu
    puts $gnu "set logscale y"
    flush $gnu
}
# gnu printing utilities
proc gnups {printer} {
    global gnu
    puts $gnu "set terminal postscript monochrome \"Helvetica\" 24 "
    puts $gnu "set output \"|lpr -P$printer \""
    regnu ; puts $gnu "set terminal x11"; puts $gnu "set output" ; regnu
}
proc gnueps {file} {
    global gnu sd
    puts $gnu "set terminal postscript eps \"Helvetica\" 24"
    puts $gnu "set output \"$sd/$file\""
    regnu ; puts $gnu "set terminal x11"; puts $gnu "set output" ; regnu
}




# procedures for axis control
proc taxisbutton {} {
    global TAXMIN TAXMAX
    set tmi $TAXMIN ; set tma $TAXMAX
    if {[winfo exists .tax]} return
    frame .tax -relief ridge -borderwidth 2
    button .tax.auto -text "auto" -command {
	set tmi [set TAXMIN ""] ; set tma [set TAXMAX ""] ; regnu }
    label .tax.l1 -text "t start: "
    entry .tax.e1  -width 10 -relief sunken -bd 2 -textvariable tmi
    bind  .tax.e1 <Return> { if {$tmi < $TAXMAX } {
	set TAXMIN $tmi ; regnu } else { set tmi $TAXMIN } }
    label .tax.l2 -text "t end: "
    entry .tax.e2  -width 10 -relief sunken -bd 2 -textvariable tma
    bind  .tax.e2 <Return> { if {$tma > $TAXMIN } {
	set TAXMAX $tma ; regnu } else { set tma $TAXMAX } }
    button .tax.ok -text "ok" -command {destroy .tax}
    pack .tax.auto .tax.l1 .tax.e1 .tax.l2 .tax.e2 .tax.ok -side left
    pack .tax
}

proc yaxisbutton {} {
    global YAXMIN YAXMAX
    set ymi $YAXMIN ; set yma $YAXMAX
    if {[winfo exists .yax]} {destroy .yax ; return}
    frame .yax -relief ridge -borderwidth 2 ; frame .yax.1 ; frame .yax.2
    button .yax.1.auto -text "auto" -command {
	set ymi [set YAXMIN ""] ; set yma [set YAXMAX ""] ; regnu }
    label .yax.1.l1 -text "y start: "
    entry .yax.1.e1  -width 10 -relief sunken -bd 2 -textvariable ymi
    bind  .yax.1.e1 <Return> { if {$ymi < $YAXMAX } {
	set YAXMIN $ymi ; regnu } else { set ymi $YAXMIN } }
    label .yax.1.l2 -text "y end: "
    entry .yax.1.e2  -width 10 -relief sunken -bd 2 -textvariable yma
    bind  .yax.1.e2 <Return> { if {$yma > $YAXMIN } {
	set YAXMAX $yma ; regnu } else { set yma $YAXMAX } }
    button .yax.1.ok -text "ok" -command {destroy .yax}
    set YSCALE 1
    radiobutton .yax.2.lin -text "lin scale" -variable YSCALE -value 1 \
	    -command { gnulin ; regnu }
    radiobutton .yax.2.log -text "log scale" -variable YSCALE -value 2 \
	    -command { gnulog ; regnu }
    pack .yax.1.auto .yax.1.l1 .yax.1.e1 .yax.1.l2 .yax.1.e2 .yax.1.ok \
	    -side left
    pack .yax.2.lin .yax.2.log -side left
    pack .yax.1 .yax.2 ; pack .yax
}


# procedure for halt button
proc haltbutton {} {
    global RUNNING
    set RUNNING 0
}


proc clearbutt {} {
    global nru SAVED
    .tiperbin.entry configure -state normal
    .binnum.entry configure -state normal
    set nru 0
}

# procedure to loop during run - start button
proc runproc {} {
    global RUNNING nru BINNUM TIMEPERBIN tmpfile COUNTPROG
    global cv1 cv2 cv3 cv0
    if {$RUNNING != 0} return
    set RUNNING 1
#    .tiperbin.entry configure -state disabled
#    .binnum.entry configure -state disabled
    .mainknobs.start configure -relief sunken
    if {0 < 1} {
	if {$nru == 0} {
	    set tmp [exec $COUNTPROG -d 1234 -t $TIMEPERBIN ]
	    exec echo $tmp >> $tmpfile
	    exec tail -n $BINNUM $tmpfile >$tmpfile.2
	    exec mv $tmpfile.2 $tmpfile
	    set cv0 [lindex $tmp 0]
	    set cv1 [lindex $tmp 1]
	    set cv2 [lindex $tmp 2]
	    set cv3 [lindex $tmp 3]

	}
    } else {regnu; .mainknobs.start configure -relief raised ; set RUNNING 0 ; return }
    regnu
    update
    
    while {[expr ($RUNNING != 0) ]} {
	set tmp [exec $COUNTPROG -d 1234 -t $TIMEPERBIN ]
	exec echo $tmp >> $tmpfile
	exec tail -n $BINNUM $tmpfile > $tmpfile.2
	exec mv $tmpfile.2 $tmpfile
	set cv0 [lindex $tmp 0]
	set cv1 [lindex $tmp 1]
	set cv2 [lindex $tmp 2]
	set cv3 [lindex $tmp 3]

	regnu

	update
	set nru [expr $nru+1]
	update
    }
    .mainknobs.start configure -relief raised
    set RUNNING 0
}


# procedure save button
proc savebutton {} {
    global sd tmpfile
    if {[winfo exists .fsel]} return
    global fname COMMENT SAVED TIMEPERBIN BINNUM nru
    if {[getfilename] == ""} return
    exec cat $tmpfile >$sd/$fname
    set outfile [open $sd/$fname a+ ]
    puts $outfile "# output of counter program. Parameters:"
    puts $outfile "# time per bin: $TIMEPERBIN Milliseconds"
    puts $outfile "# current date: [exec date]"
    puts $outfile "# comment on this run: $COMMENT"
    close $outfile
    set SAVED 1
}
proc getfilename {} {
    global fname COMMENT sd sdl
    frame .fsel -relief ridge -borderwidth 2
    frame .fsel.dir
    frame .fsel.one
    frame .fsel.three
    frame .fsel.two
    label .fsel.dir.t -text "current directory: "
    entry .fsel.dir.e -relief sunken -width 20 -bd 2 -textvariable sdl
    .fsel.dir.e xview moveto 1
    bind .fsel.dir.e <Return> {
	if {[file isdirectory $sdl]} {set sd $sdl } else {set sdl $sd}
    }
    label .fsel.one.t -text "Enter file name: "
    entry .fsel.one.e -relief sunken -width 20 -bd 2 -textvariable fname
    label .fsel.three.t -text "current comment: "
    entry .fsel.three.e -relief sunken -width 20 -bd 2 -textvariable COMMENT
    bind .fsel.one.e <Return> {
	if {[file exists $fname]} {
	    pack .fsel.two.w .fsel.two.t .fsel.two.b -side left	    
	} else { destroy .fsel }
    }
    label .fsel.two.w -bitmap warning
    label .fsel.two.t -text " File exists "
    button .fsel.two.b -text "Overwrite" -command { destroy .fsel }
    button .fsel.two.c -text "Cancel" -command { set fname "" ; destroy .fsel }
    bind .fsel.two.c <Return> {.fsel.two.c invoke}
    pack .fsel.dir.t .fsel.dir.e -side left
    pack .fsel.two.c -side right
    pack .fsel.one.t .fsel.one.e -side left
    pack .fsel.three.t .fsel.three.e -side left
    pack .fsel.dir .fsel.one .fsel.three .fsel.two
    pack .fsel
    tkwait window .fsel
    return $fname
}



# printer button
set LP "lp"
proc printbutton {} {
    global LP
    if {[winfo exists .pri]} return
    frame .pri -relief ridge -borderwidth 2
    frame .pri.one ; frame .pri.two ; frame .pri.three
    label .pri.one.t -text "PostScript printer: "
    entry .pri.one.e -width 5 -relief sunken -bd 2 -textvariable LP
    button .pri.one.b -text "Print" -command {
	gnups $LP ; destroy .pri ; return
    }
    label .pri.two.t -text "eps file : "
    entry .pri.two.e -width 5 -relief sunken -bd 2 -textvariable efna
    button .pri.two.b -text "save to" -command {
	gnueps $efna ; destroy .pri ; return 
    }
    button .pri.three.b -text "cancel" -command {destroy .pri ; return }
    pack .pri.one.t .pri.one.e .pri.one.b -side left
    pack .pri.two.t .pri.two.e .pri.two.b -side left
    pack .pri.three.b -side left
    pack .pri.one .pri.two .pri.three -side top
    pack .pri
}  

# procedure exit button
proc exitbutton {} {
    global tmpfile
    gnuclose
    if {[file exists $tmpfile]} {	
	exec rm $tmpfile
    }
    exit
}
bind .fops.exit <Return> exit











